<!DOCTYPE html><html lang="en"><head>
    <title>three.js</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <!-- <link type="text/css" rel="stylesheet" href="main.css"> -->
  </head>
  <body>
    <script async="" src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <script type="importmap">
        {
          "imports": {
            "three": "./threejs/build/three.module.js",
            "three/addons/": "./threejs/examples/jsm/"
          }
        }
      </script>

    <script type="module">
      import * as THREE from "three";
      import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
      import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
      import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
      import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
      import { OrbitControls } from "three/addons/controls/OrbitControls.js";
      import { GUI } from "three/addons/libs/lil-gui.module.min.js";

      const ENTIRE_SCENE = 0,
        BLOOM_SCENE = 1;

      const bloomLayer = new THREE.Layers();
      bloomLayer.set(BLOOM_SCENE);
      const materials = {};
      const darkMaterial = new THREE.MeshBasicMaterial({ color: "black" });

      const vert = `
    varying vec3 vNormal;
    varying vec3 camPos;
    varying vec2 vUv;

    void main() {
    vNormal = normal;
    vUv = uv;
    camPos = cameraPosition;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
`;

      const frag = `
#define NUM_OCTAVES 5
#define M_PI 3.1415926535897932384626433832795
uniform vec4 resolution;
varying vec3 vNormal;
uniform sampler2D perlinnoise;
uniform sampler2D sparknoise;
uniform float time;
uniform vec3 color0;
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color4;
uniform vec3 color5;
varying vec3 camPos;
varying vec2 vUv;

float setOpacity(float r, float g, float b, float tonethreshold) {
  float tone = (r + g + b) / 3.0;
  float alpha = 1.0;
  if(tone<tonethreshold) {
    alpha = 0.0;
  }
  return alpha;
}

vec3 rgbcol(vec3 col) {
  return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
}

vec2 rotate(vec2 v, float a) {
  float s = sin(a);
  float c = cos(a);
  mat2 m = mat2(c, -s, s, c);
  return m * v;
}

vec2 UnityPolarCoordinates (vec2 UV, vec2 Center, float RadialScale, float LengthScale){
  //https://twitter.com/Cyanilux/status/1123950519133908995/photo/1
  vec2 delta = UV - Center;
  float radius = length(delta) * 2. * RadialScale;
  float angle = atan(delta.x, delta.y) * 1.0/6.28 * LengthScale;
  return vec2(radius, angle);
}

void main() {
  vec2 olduv = gl_FragCoord.xy/resolution.xy ;
  vec2 uv = vUv ; 
  vec2 imguv = uv;
  float scale = 1.;
  olduv *= 0.5 + time; 
  olduv.y = olduv.y ;
  vec2 p = olduv*scale;
  vec4 txt = texture2D(perlinnoise, olduv);
  float gradient = dot(normalize( -camPos ), normalize( vNormal ));
  float pct = distance(vUv,vec2(0.5));

  vec3 rgbcolor0 = rgbcol(color0);
  vec3 rgbcolor1 = rgbcol(color1);
  vec3 rgbcolor2 = rgbcol(color2);
  vec3 rgbcolor5 = rgbcol(color5);

  // set solid background
  float y = smoothstep(0.16,0.525,pct);
  vec3 backcolor = mix(rgbcolor0, rgbcolor5, y);

  gl_FragColor = vec4(backcolor,1.);

  // set polar coords
  vec2 center = vec2(0.5);
  vec2 cor = UnityPolarCoordinates(vec2(vUv.x,vUv.y), center, 1., 1.);

  // set textures
  vec2 newUv = vec2(cor.x + time,cor.x*0.2+cor.y);
  vec3 noisetex = texture2D(perlinnoise,mod(newUv,1.)).rgb;    
  vec3 noisetex2 = texture2D(sparknoise,mod(newUv,1.)).rgb;    


  // set textures tones
  float tone0 =  1. - smoothstep(0.3,0.6,noisetex.r);
  float tone1 =  smoothstep(0.3,0.6,noisetex2.r);


  // set opacity for each tone
  float opacity0 = setOpacity(tone0,tone0,tone0,.29);
  float opacity1 = setOpacity(tone1,tone1,tone1,.49);

  //set final render
  if(opacity1>0.0){
    gl_FragColor = vec4(rgbcolor2,0.)*vec4(opacity1);
  } else if(opacity0>0.0){
    gl_FragColor = vec4(rgbcolor1,0.)*vec4(opacity0);
  }   
}
`;

      const vertcylinder = `
    varying vec2 vUv;

    void main() {
        vUv = uv;
        vec3 pos = vec3(position.x/1.,position.y,position.z/1.);
        if(pos.y >= 1.87){
            pos = vec3(position.x*(sin((position.y - 0.6)*1.27)-0.16),position.y,position.z*(sin((position.y - 0.6)*1.27)-0.16));
        } else{
            pos = vec3(position.x*(sin((position.y/2. -  .01)*.11)+0.75),position.y,position.z*(sin((position.y/2. -  .01)*.11)+0.75));
        }
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
    }
`;

      const fragcylinder = `
    varying vec2 vUv;
    uniform sampler2D perlinnoise;
    uniform vec3 color4;
    uniform float time;
    varying vec3 vNormal;

    vec3 rgbcol(vec3 col) {
        return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
    }

    void main() {
        vec3 noisetex = texture2D(perlinnoise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;    
        gl_FragColor = vec4(noisetex.r);

        if(gl_FragColor.r >= 0.5){
            gl_FragColor = vec4(rgbcol(color4),gl_FragColor.r);
        }else{
            gl_FragColor = vec4(0.);
        }
        gl_FragColor *= vec4(sin(vUv.y) - 0.1);
        gl_FragColor *= vec4(smoothstep(0.3,0.628,vUv.y));

    }

`;

      const vertflame = `
    varying vec2 vUv;
    varying vec3 camPos;
    varying vec3 vNormal;
    varying vec3 nois;
    uniform sampler2D noise;
    uniform float time;

    void main() {
        vUv = uv;
        camPos = cameraPosition;
        vNormal = normal;
        vec3 pos = vec3(position.x/1.,position.y,position.z/1.);
        vec3 noisetex = texture2D(noise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;
        if(pos.y >= 1.87){
            pos = vec3(position.x*(sin((position.y - 0.64)*1.27)-0.12),position.y,position.z*(sin((position.y - 0.64)*1.27)-0.12));
        } else{
            pos = vec3(position.x*(sin((position.y/2. -  .01)*.11)+0.79),position.y,position.z*(sin((position.y/2. -  .01)*.11)+0.79));
        }
        pos.xz *= noisetex.r;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
    }
`;

      const fragflame = `
    varying vec2 vUv;
    uniform sampler2D perlinnoise;
    uniform sampler2D noise;
    uniform vec3 color4;
    uniform float time;
    varying vec3 camPos;
    varying vec3 vNormal;
    varying vec3 nois;

    vec3 rgbcol(vec3 col) {
        return vec3(col.r/255.0,col.g/255.0,col.b/255.0);
    }

      
    void main() {
        // vec3 noisetex = texture2D(perlinnoise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;    
        // gl_FragColor += vec4(sin((vUv.y - time)*(20. + vUv.y)));
        vec3 noisetex = texture2D(noise,mod(1.*vec2(vUv.y-time*2.,vUv.x + time*1.),1.)).rgb;
        // nois = noisetex;
        gl_FragColor = vec4(noisetex.r);

        if(gl_FragColor.r >= 0.44){
            gl_FragColor = vec4(rgbcol(color4),gl_FragColor.r);
        }
        // else if(gl_FragColor.r >= 0.9){
        //     // gl_FragColor = vec4(rgbcol(color4),gl_FragColor.r)*0.5;
        // }
        else{
            gl_FragColor = vec4(0.);
        }
        gl_FragColor *= vec4(smoothstep(0.2,0.628,vUv.y));
        // gl_FragColor = vec4(vUv.y - 0.3 );
        // gl_FragColor = 1. - vec4(dot(normalize(vNormal),normalize(camPos)).r);
    }

`;

      let options = {
        exposure: 2.8,
        bloomStrength: 3.5,
        bloomRadius: 0.39,
        color0: [0, 0, 0],
        color1: [81, 14, 5],
        color2: [181, 156, 24],
        color3: [66, 66, 66],
        color4: [79, 79, 79],
        color5: [64, 27, 0],
      };

      // let options = {
      //   exposure: 2.8,
      //   bloomStrength: 3.5,
      //   //   bloomStrength: 0,
      //   bloomRadius: 0.39,
      //   color0: [15, 0, 10],
      //   color1: [13, 6, 5],
      //   color2: [137, 56, 10],
      //   color3: [166, 166, 166],
      //   color4: [237, 149, 67],
      //   color5: [20, 0, 51],
      // };
      let gui = new GUI();

      let bloom = gui.addFolder("Bloom");
      bloom
        .add(options, "bloomStrength", 0.0, 5.0)
        .name("bloomStrength")
        .listen();
      bloom.add(options, "bloomRadius", 0.1, 2.0).name("bloomRadius").listen();
      bloom.open();

      let color = gui.addFolder("Colors");
      color.addColor(options, "color0").name("ball0");
      color.addColor(options, "color1").name("ball1");
      color.addColor(options, "color2").name("ball2");
      color.addColor(options, "color4").name("steam");
      color.addColor(options, "color5").name("trail");
      color.open();
      gui.close();

      let scene,
        camera,
        renderer,
        controls,
        material,
        material2,
        material3,
        bloomPass,
        bloomComposer,
        composer,
        finalPass,
        finalComposer;
      const width = window.innerWidth,
        height = window.innerHeight;

      function init() {
        createScene();
        postProc();
        mesh(); 
        animatBloom();
      }

      function createScene() {
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(
          75,
          window.innerWidth / window.innerHeight,
          0.1,
          1000
        );
        camera.position.set(
          3.4369982203815655,
          3.5239085092722098,
          2.994862383531814
        );
        renderer = new THREE.WebGLRenderer();
        renderer.antialias = true;
        renderer.setClearColor(new THREE.Color("#000"));
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        controls = new OrbitControls(camera, renderer.domElement);
        document.body.appendChild(renderer.domElement);
      }

      function postProc() {
        const renderScene = new RenderPass(scene, camera);
        bloomPass = new UnrealBloomPass(
          new THREE.Vector2(window.innerWidth, window.innerHeight),
          1.5,
          0.4,
          0.85
        );
        bloomPass.threshold = options.bloomThreshold;
        bloomPass.strength = options.bloomStrength;
        bloomPass.radius = options.bloomRadius;

        bloomComposer = new EffectComposer(renderer);
        bloomComposer.addPass(renderScene);
        bloomComposer.addPass(bloomPass);
      }

      function mesh() {
        const geometry = new THREE.SphereGeometry(1, 30, 30);
        material = new THREE.ShaderMaterial({
          uniforms: {
            time: {
              type: "f",
              value: 0.0,
            },
            perlinnoise: {
              type: "t",
              value: new THREE.TextureLoader().load(
                "/threeExamples/shader/dissolve/dissolveRamp.png"
              ),
            },
            sparknoise: {
              type: "t",
              value: new THREE.TextureLoader().load(
                "/threeExamples/shader/dissolve/dissolveTex.png"
              ),
            },
            color5: {
              value: new THREE.Vector3(...options.color5),
            },
            color4: {
              value: new THREE.Vector3(...options.color4),
            },
            color3: {
              value: new THREE.Vector3(...options.color3),
            },
            color2: {
              value: new THREE.Vector3(...options.color2),
            },
            color1: {
              value: new THREE.Vector3(...options.color1),
            },
            color0: {
              value: new THREE.Vector3(...options.color0),
            },
            resolution: { value: new THREE.Vector2(width, height) },
          },
          vertexShader: vert,
          fragmentShader: frag,
        });

        const mesh = new THREE.Mesh(geometry, material);
        mesh.scale.set(0.78, 0.78, 0.78);
        mesh.position.set(1 + 0, 0, 0);
        scene.add(mesh);
      }

  
 
      function updateDraw(deltaTime) {
        material.uniforms.time.value = -deltaTime / (1000 * 2); 
        material.uniforms.color5.value = new THREE.Vector3(...options.color5); 
        material.uniforms.color3.value = new THREE.Vector3(...options.color3);
        material.uniforms.color2.value = new THREE.Vector3(...options.color2);
        material.uniforms.color1.value = new THREE.Vector3(...options.color1);
        material.uniforms.color0.value = new THREE.Vector3(...options.color0);
      }

      function animatBloom(deltaTime) {
        requestAnimationFrame(animatBloom);
        updateDraw(deltaTime);
        controls.update();
        bloomPass.strength = options.bloomStrength;
        bloomPass.radius = options.bloomRadius;
        bloomComposer.render();
      }

      function handleResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      }

      window.addEventListener("load", init);
      window.addEventListener("resize", handleResize, false);
    </script>
  

 